import Head from 'next/head';
import Box from '@mui/material/Box';
import RootPropTable from '../../../components/prop-tables/RootPropTable';
import ColumnOptionsTable from '../../../components/prop-tables/ColumnOptionsTable';
import StateOptionsTable from '../../../components/prop-tables/StateOptionsTable';
import CustomizeComponentExample from '../../../examples/customize-global-filter-component';
import RemoteExample from '../../../examples/remote';

<Head>
  <title>
    {'Global Filtering/Search Feature Guide - Material React Table V1 Docs'}
  </title>
  <meta
    name="description"
    content="How to use, customize, or disable the global filter and search features in Material React Table"
  />
</Head>

## Global Filtering (Search) Feature Guide

Material React Table has a powerful built-in global filtering (search) feature that uses a fuzzy matching algorithm and ranks/sorts the results based on how closely rows match the search query. In this guide, we'll cover how to use, customize, or disable the global filter and search features to fit your needs.

### Relevant Props

<RootPropTable
  onlyProps={
    new Set([
      'enableGlobalFilter',
      'enableGlobalFilterModes',
      'enableGlobalFilterRankedResults',
      'enableFilterMatchHighlighting',
      'getColumnCanGlobalFilter',
      'globalFilterFn',
      'globalFilterModeOptions',
      'manualFiltering',
      'muiSearchTextFieldProps',
      'onGlobalFilterChange',
      'onGlobalFilterFnChange',
      'onShowGlobalFilterChange',
      'positionGlobalFilter',
      'renderGlobalFilterModeMenuItems',
    ])
  }
/>

### Relevant Column Options

<ColumnOptionsTable
  onlyProps={new Set(['enableGlobalFilter', 'enableFilterMatchHighlighting'])}
/>

### Relevant State Options

<StateOptionsTable
  onlyProps={new Set(['globalFilter', 'globalFilterFn', 'showGlobalFilter'])}
/>

### Disable Global Filtering

You can either disable the global filter feature entirely or disable it for specific columns.

#### Disable Global Filtering per Column

If you simply want to not include a column as one of the columns that the global filter scans through during filtering, you can set the `enableGlobalFilter` option to `false` for that column.

```tsx
const columns = [
  {
    accessorKey: 'id',
    header: 'Id',
    enableGlobalFilter: false, // do not scan this column during global filtering
  },
  {
    accessorKey: 'name',
    header: 'Name',
  },
];
```

#### Disable Global Filter Feature

You can disable the global filtering feature and hide the search icon by setting the `enableGlobalFilter` prop to `false`.

```tsx
<MaterialReactTable
  columns={columns}
  data={data}
  enableGlobalFilter={false} //disable search feature
/>
```

### Filter Match Highlighting

> New in v1.6

Filter match highlighting is a new featured enabled by default that will highlight text in the table body cells that matches the current search query with a shade of the <Box component="span" color="warning.main">`theme.palette.warning.main`</Box> color.

If you are using a custom `Cell` render override for a column, you will need to use the `renderedCellValue` prop instead of `cell.getValue()` to preserve the filter match highlighting.

```jsx
const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
    Cell: ({ renderedCellValue }) => <span>{renderedCellValue}</span>, // use renderedCellValue instead of cell.getValue()
  },
];
```

#### Disable Filter Match Highlighting

Filter match highlighting can be disabled by setting the `enableFilterMatchHighlighting` prop to `false`.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  enableFilterMatchHighlighting={false}
/>
```

### Client-Side Global Filtering

Client-side filtering (and global filtering) is enabled by default. This means that the search box will scan through all columns and try to find matches for the search term.

#### Global Filter Function

You can use any of the built-in `filterFns` or any of the custom filter functions that you have defined in the `filterFns` prop, just like you would with the column filters.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  globalFilterFn="contains" //turn off fuzzy matching and use simple contains filter function
/>
```

Or a custom filter function:

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  filterFns={{
    myCustomFilterFn: (row, id, filterValue) =>
      row.getValue(id).startsWith(filterValue),
  }}
  globalFilterFn="myCustomFilterFn" //set the global filter function to myCustomFilterFn
/>
```

The default global filter function is set to `fuzzy`, which is a filtering algorithm based on the popular `match-sorter` [library from Kent C. Dodds](https://www.npmjs.com/package/match-sorter), though you can change the global filter function by setting the `globalFilterFn` prop.

#### Ranked Results

If you keep the default `fuzzy` filterFn option as the global filter function, you get an extra ranked results feature enabled by default. This means that when a user searches with the search box, the results will be sorted by the closest match first instead of the order the data was defined in.

The ranked results feature will disable itself automatically if a sort direction is applied to a column, if any sub-rows are expanded, or if any of the `manual` props are set to `true`.

If you do not want ranked results to be enabled at all, but you still want fuzzy matching, you can set the `enableGlobalFilterRankedResults` prop to `false`.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  enableGlobalFilterRankedResults={false} //preserve the order of the data when fuzzy match searching
/>
```

#### Global Filter Modes

Similar to the column filter modes, you can enable the user to be able to choose between multiple different filter modes for the global filter with the `enableGlobalFilterModes` prop. You can then customize which filter modes are available in the drop-down by setting the `globalFilterModeOptions` prop or by rendering your own custom menu items with the `renderGlobalFilterModeMenuItems` prop.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  enableGlobalFilterModes //enable the user to choose between multiple search filter modes
  globalFilterModeOptions={['fuzzy', 'startsWith']} //only allow the user to choose between fuzzy and startsWith filter modes
/>
```

#### Show Search Field by Default

Additionally, if you want to show the search text box by default and not hide it behind the search icon, you can set the `showGlobalFilter` state to `true` in the `initialState`.

### Manual Server-Side Global Filtering

A very common use case when you have a lot of data is to filter the data on the server, instead of client-side. In this case, you will want to set the `manualFiltering` prop to `true` and manage the `globalFilter` state yourself like in the example below (can work in conjuntion with [manual column filtering](https://www.material-react-table.com/docs/guides/column-filtering#manual-server-side-column-filtering)).

```tsx
// You can manage and have control over the columnFilters state yourself
const [globalFilter, setGlobalFilter] = useState('');
const [data, setData] = useState([]); //data will get updated after re-fetching

useEffect(() => {
  const fetchData = async () => {
    // send api requests when columnFilters state changes
    const filteredData = await fetch();
    setData([...filteredData]);
  };
}, [globalFilter]);

return (
  <MaterialReactTable
    columns={columns}
    data={data} // this will already be filtered on the server
    manualFiltering //turn off client-side filtering
    onGlobalFilterChange={setGlobalFilter} //hoist internal global state to your state
    state={{ globalFilter }} //pass in your own managed globalFilter state
  />
);
```

> Specifying `manualFiltering` turns off all client-side filtering and assumes that the `data` you pass to `<MaterialReactTable />` is already filtered.

Here is the full Remote Data example showing off server-side **filtering**, pagination, and sorting.

<RemoteExample />

### Customize Global Filter Position

You can customize the position of the global filter (search box) in the top toolbar by setting the `positionGlobalFilter` prop to `left` or `right`. It is shown on the right by default.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  positionGlobalFilter="left" //show the global filter on the left side of the top toolbar
  initialState={{
    showGlobalFilter: true, //show the global filter by default
  }}
/>
```

### Customize the Search Text Field

You can customize the search text field by passing in props to the `muiSearchTextFieldProps` prop. This is useful if you want to customize the placeholder text, add styles, or any other text field props.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiSearchTextFieldProps={{
    placeholder: 'Search all users',
    sx: { minWidth: '300px' },
    variant: 'outlined',
  }}
/>
```

<CustomizeComponentExample />

View Extra Storybook **[Examples](https://www.material-react-table.dev/?path=/story/features-search-examples)**
